package liveness.graph;


public class Graph{
	
	/***/
    int nodecount=0;
    /***/
    NodeList mynodes, mylast;
    
    /**
     * 
     * */
    public NodeList nodes(){
        return mynodes;
    } 

    /**
     * 
     * */
    public Node newNode(){
        return new Node(this);
    }

    /**
     * 
     * */
    void check(Node n){
        if (n.mygraph != this)
            throw new Error("Graph.addEdge using nodes from the wrong graph");
    }

    /**
     * 
     * */
    static boolean inList(Node a, NodeList l){
        for(NodeList p=l; p!=null; p=(NodeList) p.tail)
            if (p.head==a)
                return true;
        return false;
    }

    /**
     * 
     * */
    public void addEdge(Node from, Node to){
        check(from);
        check(to);
        if (from.goesTo(to))
            return;
        to.preds=new NodeList(from, to.preds);
        from.succs=new NodeList(to, from.succs);
    }

    /**
     * 
     * */
    public NodeList delete(Node a, NodeList l){
        if (l==null)
            throw new Error("Graph.rmEdge: edge nonexistent");
        else if (a==l.head)
            return (NodeList) l.tail;
        else
            return new NodeList(l.head, delete(a, (NodeList)l.tail));
    }

    /**
     * 
     * */
    public void rmEdge(Node from, Node to){
        to.preds=delete(from,to.preds);
        from.succs=delete(to,from.succs);
    }
    
    /**
     * 
     * */
    public NodeList suc(Node v){
    	return v.succ();
    }
    
    /**
     * 
     * */ 
    public NodeList adj(Node v){
    	return v.adj();
    }

    /**
     * Print a human-readable dump for debugging.
     */
    public void show(java.io.PrintStream out){
        for (NodeList p=nodes(); p!=null; p=(NodeList) p.tail){
            Node n = p.head;
            out.print(n.toString());
            out.print(": ");
            for(NodeList q=n.succ(); q!=null; q=(NodeList) q.tail)
            {
                out.print(q.head.toString());
                out.print(" ");
            }
            out.println();
        }
    }

    /**
     * 
     * */
	public int size() {
		return mynodes.size();
	}
	
	/**
	 * 
	 * */
	public Node getNode(int i){
		return mynodes.get(i);
	}
}